package com.tfswx.fljdmxyy.validation;

import cn.hutool.core.bean.BeanUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import javax.validation.Constraint;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import javax.validation.Payload;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 开始时间和结束时间的校验
 *
 * @author ricky
 * @date 2021/11/30
 */
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = DateValid.Validator.class)
public @interface DateValid {

    String kssjField();

    String jssjField();

    String message() default "{path}{kssjField}【{kssj}】-不能大于{path}{jssjField}【{jssj}】";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};

    @Slf4j
    class Validator implements ConstraintValidator<DateValid, Object> {

        String kssjField;
        String jssjField;

        @Override
        public void initialize(DateValid constraintAnnotation) {
            kssjField = constraintAnnotation.kssjField();
            jssjField = constraintAnnotation.jssjField();
        }

        @Override
        public boolean isValid(Object value, ConstraintValidatorContext context) {
            // 获取开始时间
            Object kssjObj = BeanUtil.getProperty(value, kssjField);
            Date kssj = getDate(kssjObj);

            // 获取结束时间
            Date jssjObj = BeanUtil.getProperty(value, jssjField);
            Date jssj = getDate(jssjObj);

            Map<String, Object> map = new HashMap<>();
            map.put("kssj", kssj);
            map.put("jssj", jssj);
            String path = ValidUtil.getPath(context);
            if (StringUtils.isNotBlank(path)) {
                path += ".";
            }
            map.put("path", path);
            ValidUtil.setParam(context, map);
            if (kssj != null && jssj != null) {
                return !kssj.after(jssj);
            }
            return true;
        }

        private Date getDate(Object value) {
            if (value == null) {
                return null;
            }
            if (value instanceof Date) {
                return (Date) value;
            }
            if (value instanceof LocalDate) {
                return Date.from(((LocalDate) value).atStartOfDay(ZoneId.systemDefault()).toInstant());
            }
            log.warn("未知类型");
            return null;
        }
    }
}
